package com.example.cc.client.service.impl;

import com.example.cc.client.properties.ConfigCenterProperties;
import com.example.cc.client.service.ClientConfigService;
import com.example.cc.client.utils.HttpUtil;
import com.example.cc.common.constants.ConfigConstants;
import com.example.cc.common.constants.EndPoint;
import lombok.NoArgsConstructor;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;

@Service
@NoArgsConstructor
@SuppressWarnings("all")
public class ClientConfigServiceImpl implements ClientConfigService {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private ConfigCenterProperties configCenterProperties;

    private static String BASE_URL;

    @PostConstruct
    public void init() {
        BASE_URL = configCenterProperties.getServerUrl() + ConfigConstants.API_PATH;
    }

    /**
     * 根据key获取配置信息
     */
    private Object getOne(String key) {
        ResponseEntity<Object> response = restTemplate.exchange(BASE_URL + "/get/{key}", HttpMethod.GET,
                null, Object.class, key);
        if (response.getStatusCode() == HttpStatus.NOT_FOUND) {
            return null;
        } else if (response.getStatusCode().is2xxSuccessful()) {
            return response.getBody();
        } else {
            throw new RuntimeException("Failed to get config by key");
        }
    }

    /**
     * 获取所有配置信息
     */
    private Map<String, Object> doGetAll() {
        ResponseEntity<Map<String, Object>> response = restTemplate.exchange(BASE_URL + EndPoint.CONFIG_GET_ALL,
                HttpMethod.GET, null, new ParameterizedTypeReference<>() {
                });
        if (response.getStatusCode().is2xxSuccessful()) {
            return response.getBody();
        } else {
            throw new RuntimeException("Failed to get all configs");
        }
    }

    /**
     * 创建配置信息
     */
    public String doCreate(String key, Object value) {
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("key", key);
        params.add("value", value);
        ResponseEntity<String> response = HttpUtil.exchange(
                BASE_URL + EndPoint.CONFIG_CREATE,
                HttpMethod.POST,
                new HttpEntity<>(params),
                String.class
        );
        if (response.getStatusCode() == HttpStatus.CONFLICT) {
            return response.getBody(); // 返回冲突信息
        } else if (response.getStatusCode().is2xxSuccessful()) {
            return "Configuration created";
        } else {
            throw new RuntimeException("Failed to create config");
        }
    }

    /**
     * 更新配置信息
     */
    private String doUpdate(String key, Object value) {
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("value", value);

        ResponseEntity<String> response = restTemplate.exchange(BASE_URL + "/{key}", HttpMethod.PUT, new HttpEntity<>(params), String.class, key);
        if (response.getStatusCode().is2xxSuccessful()) {
            return "Configuration updated";
        } else {
            throw new RuntimeException("Failed to update config");
        }
    }

    /**
     * 删除配置信息
     */
    private String doDelete(String key) {
        ResponseEntity<String> response = restTemplate.exchange(BASE_URL + "/{key}", HttpMethod.DELETE, null, String.class, key);
        if (response.getStatusCode() == HttpStatus.NOT_FOUND) {
            return "Configuration not found";
        } else if (response.getStatusCode().is2xxSuccessful()) {
            return "Configuration deleted";
        } else {
            throw new RuntimeException("Failed to delete config");
        }
    }


    @Override
    public Object getConfig(String key) {
        // return restTemplate.getForObject(configCenterProperties.getServerUrl() + "/api/config/get?key=" + key, Object.class);
        return getOne(key);
    }

    @Override
    public void addConfig(String key, Object value) {
        doCreate(key, value);
    }

    @Override
    public void updateConfig(String key, Object value) {
        doUpdate(key, value);
    }

    @Override
    public void deleteConfig(String key) {
        doDelete(key);
    }

    @Override
    public Map<String, Object> loadAppAllConfig() {
        if (2 < 1) {
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(BASE_URL)
                    .path("/api/config/all");
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json");
            ResponseEntity<Map<String, Object>> response = restTemplate.exchange(
                    builder.toUriString(),
                    HttpMethod.GET,
                    new HttpEntity<>(headers),
                    new ParameterizedTypeReference<>() {
                    }
            );
            if (response.getStatusCode().is2xxSuccessful()) {
                return response.getBody();
            } else {
                throw new RuntimeException("Failed to fetch configurations from config center");
            }
        }
        return doGetAll();
    }
}
